<template>
  <div
    :class="{
      viewBox: true,
      active: editorItem.isEdit,
      js_viewComponentWrap: true
    }"
    @click="handleClickView"
  >
    <span class="formProperty"> {{ attrs.curNodePath }}</span>
    <div v-if="editorItem.isEdit" class="editBar">
      <button
        :disabled="editorItem.toolBar.moveUpDisabled"
        class="toolBarBtn"
        title="上移"
        type="button"
        @click="$emit('onOperate', { item: editorItem, command: 'moveUp' })"
      >
        <el-icon><CaretTop /></el-icon>
      </button>
      <button
        :disabled="editorItem.toolBar.moveDownDisabled"
        class="toolBarBtn"
        title="下移"
        type="button"
        @click="$emit('onOperate', { item: editorItem, command: 'moveDown' })"
      >
        <el-icon><CaretBottom /></el-icon>
      </button>
      <button
        :disabled="editorItem.toolBar.copyDisabled"
        class="toolBarBtn"
        title="复制"
        type="button"
        @click="$emit('onOperate', { item: editorItem, command: 'copy' })"
      >
        <el-icon><CopyDocument /></el-icon>
      </button>
      <button
        :disabled="editorItem.toolBar.removeDisabled"
        class="toolBarBtn"
        title="移除"
        type="button"
        @click="$emit('onOperate', { item: editorItem, command: 'remove' })"
      >
        <el-icon><Delete /></el-icon>
      </button>
    </div>
    <SchemaField v-bind="attrs"> </SchemaField>

    <NestedEditor
      v-if="showNestedEditor?.(editorItem)"
      :child-component-list="editorItem.childList"
      :drag-options="dragOptions"
      :form-data="formData"
      :form-props="formProps"
    >
    </NestedEditor>
  </div>
</template>
<script lang="ts">
export default {
  name: 'ViewComponentWrap'
}
</script>
<script lang="ts" setup>
import { SchemaField, globalOptions } from '@lljj/vue3-form-element'
import NestedEditor from './NestedEditor.vue'
import { editorItem2SchemaFieldProps } from '../common/editorData'
import {
  CaretTop,
  CaretBottom,
  CopyDocument,
  Delete
} from '@element-plus/icons-vue'
import { PropType } from 'vue'

const props = defineProps({
  showNestedEditor: {
    type: Function as PropType<(editorItem: any) => boolean>,
    default: (editorItem: any) => ({})
  },
  editorItem: {
    type: Object as PropType<{ isEdit: boolean }>,
    default: () => ({ isEdit: false })
  },
  dragOptions: {
    type: Object,
    default: () => ({})
  },
  formData: {
    type: Object,
    default: () => ({})
  },
  formProps: {
    type: null,
    default: null
  }
})

const editorEvent = inject('editorEvent') as {
  setCurEditorItem: (item: any) => void
}

const attrs = computed(() => ({
  formProps: props.formProps,
  globalOptions,
  ...editorItem2SchemaFieldProps(props.editorItem, props.formData)
}))

const instance = getCurrentInstance()?.proxy

const closeHandle = (event: MouseEvent) => {
  // 点击的自己兄弟view关闭自己
  const $el = instance?.$el
  const target = event.target as HTMLDivElement
  const isChildEle = $el.contains(target)
  const parentWrapEle = target?.closest?.('.js_viewComponentWrap')

  // 点击非自身的item 关闭自己，或者点击了自己的子item 关闭自己
  if (
    (!isChildEle && parentWrapEle) ||
    (isChildEle && $el !== parentWrapEle && $el.contains(parentWrapEle))
  ) {
    hideEditForm()
  }
}

const setCurEditorItem = (editorItem: any) => {
  editorEvent.setCurEditorItem(editorItem)
  // this.dispatch('Editor', 'onSetCurEditorItem', {
  //   editorItem
  // })
}
const hideEditForm = () => {
  // eslint-disable-next-line vue/no-mutating-props
  props.editorItem.isEdit = false
  document.removeEventListener('click', closeHandle, true)
  setCurEditorItem(null)
}
onBeforeUnmount(() => {
  hideEditForm()
})
// 点击只能打开，并且打开状态下只能执行一次
const handleClickView = (e: CustomEvent) => {
  // 阻止浏览器默认事件
  e.stopPropagation()
  if (!props.editorItem.isEdit) {
    showEditForm()
  } else {
    // 设置当前选中tab
    setCurEditorItem(props.editorItem)
  }
}

const updateEditorIsEdit = (show: boolean) => {
  // eslint-disable-next-line vue/no-mutating-props
  props.editorItem.isEdit = show
}
// 显示编辑form
const showEditForm = () => {
  updateEditorIsEdit(true)
  // 点击其它弹窗关闭这里
  document.addEventListener('click', closeHandle, true)
  setCurEditorItem(props.editorItem)
}
</script>

<style lang="less" scoped>
.viewBox {
  position: relative;
  margin-bottom: 10px;
  padding: 30px 10px 10px;
  cursor: move;
  outline: none;
  border: 1px dashed #bbb;
  overflow: hidden;
  background-color: #ffffff;
  .draggableSlot {
    cursor: no-drop;
  }
  &:after {
    pointer-events: none;
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    transition: box-shadow 0.3s ease;
    z-index: 2;
  }

  &.active {
    border: 1px dashed transparent;
    &:after {
      box-shadow: 0 0 2px 1px var(--color-primary) inset;
    }
  }
}
.formProperty {
  position: absolute;
  padding: 10px;
  top: 0;
  right: 0;
  font-size: 13px;
}

.editBar {
  position: absolute;
  bottom: 0;
  right: 0;
  height: 26px;
  border-top-left-radius: 8px;
  background: var(--color-primary);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0 10px;
  & > .toolBarBtn {
    -webkit-appearance: none;
    appearance: none;
    padding: 0;
    margin: 0;
    outline: none;
    border: none;
    cursor: pointer;
    display: block;
    width: 26px;
    line-height: 30px;
    text-align: center;
    background-color: transparent;
    font-size: 16px;
    color: #ffffff;
    &[disabled] {
      display: none;
    }
    &:hover {
      opacity: 0.6;
    }
  }
}
</style>
